home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / SWAG / SWAGA_C / CURSOR.SWG / 0026_Animated Cursor.pas < prev   
Pascal/Delphi Source File  |  1995-05-26  |  5KB  |  169 lines

  1.  
  2. { Updated CURSOR.SWG on May 26, 1995 }
  3.  
  4. {
  5. Hi everyone.  Recently, I made a program to animate the cursor, and
  6. when I added support for hiding and showing the cursor, my program
  7. ceased to work like it should (all int 10h functions (video) didn't
  8. work right.)  If anyone has any suggestions, optimizations, or ways
  9. to get this to take up less memory, please reply.
  10.  
  11. ----8<-cut-here-
  12. Program AnimateCursor;
  13. { AnimateCursor Copyright (C) 1995 by Jonathan Anderson }
  14. { This program does what it says -- it makes the cursor move up and down }
  15. { thanks to John Baldwin for nice description of cursor handling }
  16.  
  17. {-$DEFINE Debug}        { Define this if changing the code }
  18. {$DEFINE Use286}       { Define this to use 286 code }
  19.  
  20. {$IFDEF Debug}
  21.  
  22. {$M $1000,0,0}   { 4K stack, no heap }
  23. {$A+,B-,D+,E-,F-,G-,I-,L+,N-,O-,R-,S+,V+,X-}     { TP6 compile options }
  24.  
  25. {$ELSE}
  26.  
  27. {$M $400,0,0}    { 1K stack, no heap }
  28. {$A+,B-,D-,E-,F-,G-,I-,L-,N-,O-,R-,S-,V-,X-}
  29.  
  30. {$ENDIF}
  31.  
  32. {$IFDEF Use286}
  33. {$G+}
  34. {$ENDIF}
  35.  
  36. Uses Dos;
  37.  
  38. Var OldInt1C, OldInt09 : Procedure;
  39.     OldInt10           : Pointer;     { status = cursor blink pattern }
  40.     x, z, status       : Byte;        { x = top scan line for cursor }
  41.     y                  : Boolean;     { z = width (in scan lines) of cursor }
  42.                                       { y = cursor going up (F) or down (T) }
  43.  
  44. Procedure RemoveAnimate; Assembler;
  45. Asm                  { thanks to Luis Mezquita Raya for this... }
  46.   cli
  47.   mov   ah,1
  48.   mov   ch,6                { this procedure (c) Jul 94 Luis Mezquita Raya }
  49.   mov   cl,7
  50.   int   10h
  51.   mov   ah,49h
  52.   mov   es,PrefixSeg
  53.   push  es
  54.   mov   es,es:[2ch]
  55.   int   21h
  56.   pop   es
  57.   mov   ah,49h
  58.   int   21h
  59.   sti
  60. End;
  61.  
  62. {$F+}
  63. Procedure NewInt09; Interrupt;      { KBD handler for unloading hotkey }
  64. Var KB : Byte;
  65. Begin
  66.   KB := Port[$60];
  67.   Inline($9C);                      { pushf }
  68.   OldInt09;                         { call old interrupt }
  69.   If KB = 88 Then                   { Use F12 to unload from memory }
  70.     Begin
  71.       SetIntVec($1C, @OldInt1C);
  72.       SetIntVec($10, OldInt10);
  73.       SetIntVec($09, @OldInt09);
  74.       RemoveAnimate;
  75.     End;
  76. End;
  77.  
  78. Procedure NewInt10; Interrupt; Assembler;  { handler to allow programs  }
  79. Asm                                        { to hide & show cursor...   }
  80. {$IFDEF Use286}                            { right now, it doesn't work }
  81.   pusha
  82. {$ELSE}
  83.   push  ax
  84.   push  bx
  85.   push  cx
  86.   push  dx
  87.   push  si
  88.   push  di
  89. {$ENDIF}
  90.   cmp   ah,1                               { check for cursor change }
  91.   jnz   @Skip                              { request & jump if not   }
  92.   mov   status,ch
  93.   and   status,60h                         { isolate bits 5 and 6 }
  94. @Skip:
  95. {$IFDEF Use286}
  96.   popa
  97. {$ELSE}
  98.   pop   ax
  99.   pop   bx
  100.   pop   cx
  101.   pop   dx
  102.   pop   si
  103.   pop   di
  104. {$ENDIF}
  105.   call  oldint10                           { call olt interrupt }
  106. End;
  107.  
  108. Procedure NewInt1C; Interrupt;             { timer handler; changes cursor }
  109. Var ctype : Byte;
  110. Begin
  111.   If (x=129) or (x=143-z) Then y := Not(y);  { reverse direction of cursor }
  112.   If y Then Asm dec x End                  { why use Inc() and Dec() ? }
  113.   Else Asm inc x End;
  114.   ctype := status OR x;            { combine status bits with position bits }
  115.   Asm
  116.     mov  ah,1                      { request cursor change }
  117.     mov  ch,ctype                  { set top scan line }
  118.     mov  cl,ctype                  { set bottom scan line }
  119.     add  cl,z
  120.     call OldInt10      { call oldint instead of wasting time calling new one }
  121.   End;
  122.   Inline($9C);         { pushf }
  123.   OldInt1C;            { call old interrupt }
  124. End;
  125. {$F-}
  126.  
  127. Begin
  128.   x := 129;  { had to mess with this value for use of all scan lines in char }
  129.   z := 1;                    { cusor width = 1 }
  130.   status := 0;               { normal cursor }
  131.   y := True;                 { MUST be true...}
  132.   GetIntVec($09, @OldInt09);
  133.   SetIntVec($09, @NewInt09);
  134.   GetIntVec($10, OldInt10);
  135.   SetIntVec($10, @NewInt10); { comment this line for prog. to work w/o int10 }
  136.   GetIntVec($1C, @OldInt1C);
  137.   SetIntVec($1C, @NewInt1C);
  138.   Keep(0);                   { terminate, stay resident }
  139. End.
  140.  
  141. (*
  142.   From: Kelly Small
  143.  
  144. You don't restore the registers properly during the Int $10 ISR.
  145. You need to pop them in the reverse order that they were pushed:
  146.  
  147. >Procedure NewInt10; Interrupt; Assembler;  { handler to allow programs  }
  148. >Asm                                        { to hide & show cursor...   }
  149. >  push  ax
  150. >  push  bx
  151. >  push  cx
  152. >  push  dx
  153. >  push  si
  154. >  push  di
  155.  
  156.  
  157. >  pop   ax
  158. >  pop   bx
  159. >  pop   cx
  160. >  pop   dx
  161. >  pop   si
  162. >  pop   di
  163.  
  164. After this you would have ax = di
  165.                           bx = si etc.
  166.  
  167. Reverse the order of your pop's and it should work.
  168. *)
  169.